package com.scwatch.core.web.back;

import com.alibaba.fastjson.JSONObject;
import com.scwatch.common.office.ExcelUtil;
import com.scwatch.common.orm.RowSide;
import com.scwatch.common.upload.UploadResult;
import com.scwatch.common.util.Dates;
import com.scwatch.common.web.Servlets;
import com.scwatch.core.constant.Constants;
import com.scwatch.core.domain.*;
import com.scwatch.core.service.*;
import com.scwatch.core.support.Backends;
import com.scwatch.core.support.Context;
import com.scwatch.ext.domain.LiveBroadcast;
import com.scwatch.ext.service.LiveBroadcastService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.util.CollectionUtils;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.util.*;

import static com.scwatch.core.constant.Constants.*;

/**
 * CommentController
 * 评论管理
 * @author gjl
 */
@Controller
@RequestMapping("/core/comment")
public class CommentController {
    private static final Logger logger = LoggerFactory.getLogger(CommentController.class);

    public CommentController(CommentService service) {
        this.service = service;
    }

    /**
     * 查询评论
     * @param pageable 分页对象
     * @param request
     * @param modelMap
     * @return 结果页面
     */
    @RequiresPermissions("core:comment:list")
    @RequestMapping("list.do")
    public String list(@PageableDefault(sort = "id", direction = Direction.DESC) Pageable pageable, HttpServletRequest request,Model modelMap) {
        Site site = Context.getCurrentSite();

        // 评论指向的新闻或者专题
        String fid = request.getParameter("infoid");
        // 评论类型
//        String ftype = request.getParameter("ftype");
//        logger.debug(ftype);

        Map<String, String[]> params = Servlets.getParamValuesMap(request, Constants.SEARCH_PREFIX);

        if(StringUtils.isNotBlank(fid)){
            params.put("EQ_fid", new String[]{fid.toString()});
            modelMap.addAttribute("infoid", fid);
        }
//        params.put("EQ_ftype", new String[]{ftype.toString()});
        Page<Comment> pagedList = service.findAll(site.getId(), params, pageable,true);

        modelMap.addAttribute("pagedList", pagedList);
//        modelMap.addAttribute("ftype", ftype);
        return "core/comment/comment_list";
    }

// @RequiresPermissions("core:comment:list")
//    @RequestMapping("list.do")
//    public String list(
//            @PageableDefault(sort = "id", direction = Direction.DESC) Pageable pageable,
//            HttpServletRequest request, org.springframework.ui.Model modelMap) {
//        Site site = Context.getCurrentSite();
//
//
//        String infoid = request.getParameter("infoid");
//        String ftype =request.getParameter("ftype");
//
//        Map<String, String[]> params = Servlets.getParamValuesMap(request,
//                Constants.SEARCH_PREFIX);
////        Map<String, String[]> params = new HashMap<>();
//        params.put("EQ_fid", new String[]{infoid.toString()});
//        params.put("EQ_ftype", new String[]{ftype.toString()});
//        Page<Comment> pagedList = service.findAll(site.getId(), params,
//                pageable);
//        modelMap.addAttribute("pagedList", pagedList);
//        modelMap.addAttribute("infoid", infoid);
//        modelMap.addAttribute("ftype", ftype);
//        return "core/comment/comment_list";
//    }


//    @RequiresPermissions("core:comment:comments")
//    @RequestMapping("comment.do")
//    public String Comment(
//            @PageableDefault(sort = "id") org.springframework.ui.Model modelMap,Integer id) {
//        List commentList = service.queryComment(id);
//        System.out.println(JSONObject.toJSONString(commentList));
//        modelMap.addAttribute("pagedList", commentList);
//        return "core/comment/comment_list";
//    }

    @RequiresPermissions("core:comment:create")
    @RequestMapping("create.do")
    public String create(Integer id, org.springframework.ui.Model modelMap, HttpServletRequest request) {
        if (id != null) {
            Comment bean = service.get(id);
            modelMap.addAttribute("bean", bean);
        }

        String infoid = request.getParameter("infoid");
        String ftype = request.getParameter("ftype");
        modelMap.addAttribute(OPRT, CREATE);
        modelMap.addAttribute("infoid", infoid);
        modelMap.addAttribute("ftype", ftype);
        return "core/comment/comment_form";
    }

    @RequiresPermissions("core:comment:edit")
    @RequestMapping("edit.do")
    public String edit(
            Integer id,
            Integer position,
            @PageableDefault(sort = "id", direction = Direction.DESC) Pageable pageable,
            HttpServletRequest request, org.springframework.ui.Model modelMap) {
        Site site = Context.getCurrentSite();
        Comment bean = service.get(id);
        String infoid = request.getParameter("infoid");
        String ftype = request.getParameter("ftype");
        Backends.validateDataInSite(bean, site.getId());
        Map<String, String[]> params = Servlets.getParamValuesMap(request,
                Constants.SEARCH_PREFIX);
        RowSide<Comment> side = service.findSide(site.getId(), params, bean,
                position, pageable.getSort());
        modelMap.addAttribute("bean", bean);
        modelMap.addAttribute("side", side);
        modelMap.addAttribute("position", position);
        modelMap.addAttribute("infoid", infoid);
        modelMap.addAttribute("ftype", ftype);
        modelMap.addAttribute(OPRT, EDIT);
        return "core/comment/comment_form";
    }

    @RequiresPermissions("core:comment:save")
    @RequestMapping("save.do")
    public String save(Comment bean, Integer parentId, String redirect,
                       HttpServletRequest request, RedirectAttributes ra) {
        Integer siteId = Context.getCurrentSiteId();
        Integer userId = Context.getCurrentUserId();
        service.save(bean, userId, siteId, parentId);
        logService.operation("opr.comment.add",
                StringUtils.substring(bean.getText(), 0, 150), null,
                bean.getId(), request);
        logger.info("save Comment, id={}.", bean.getId());
        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        if (Constants.REDIRECT_LIST.equals(redirect)) {
            return "redirect:list.do";
        } else if (Constants.REDIRECT_CREATE.equals(redirect)) {
            return "redirect:create.do";
        } else {
            ra.addAttribute("id", bean.getId());
            return "redirect:edit.do";
        }
    }

    @RequiresPermissions("core:comment:update")
    @RequestMapping("update.do")
    public String update(@ModelAttribute("bean") Comment bean,
                         Integer position, String redirect, HttpServletRequest request,
                         RedirectAttributes ra) {
        Backends.validateDataInSite(bean, Context.getCurrentSiteId());
        service.update(bean);

        String infoid = request.getParameter("infoid");
        String ftype = request.getParameter("ftype");

        logger.info("update Comment, id={}.", bean.getId());
        logService.operation("opr.comment.edit",
                StringUtils.substring(bean.getText(), 0, 150), null,
                bean.getId(), request);
        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        if (Constants.REDIRECT_LIST.equals(redirect)) {
            return "redirect:list.do";
        } else {
            ra.addAttribute("id", bean.getId());
            ra.addAttribute("position", position);
            ra.addAttribute("infoid", infoid);
            ra.addAttribute("ftype", ftype);
            return "redirect:edit.do";
        }
    }

    /**
     * 删除评论
     * @param ids 评论id
     * @param request
     * @param ra
     * @return
     */
    @RequiresPermissions("core:comment:delete")
    @RequestMapping("delete.do")
    public String delete(Integer[] ids, HttpServletRequest request,
                         RedirectAttributes ra) {
        Site site = Context.getCurrentSite();
        String infoid = request.getParameter("infoid");
        validateIds(ids, site.getId());
        Comment[] beans = service.delete(ids);
        for (Comment bean : beans) {
            logService.operation("opr.comment.delete",
                    StringUtils.substring(bean.getText(), 0, 150), null,
                    bean.getId(), request);
            logger.info("delete Comment, id={}.", bean.getId());
        }
        String ftype = request.getParameter("ftype");
        ra.addFlashAttribute(MESSAGE, DELETE_SUCCESS);
        ra.addAttribute("infoid", infoid);
        ra.addAttribute("ftype", ftype);
        return "redirect:list.do";
    }

    /**
     * 评论审核
     * @param ids 评论id
     * @param request
     * @param ra
     * @return 结果页面
     */
    @RequiresPermissions("core:comment:audit")
    @RequestMapping("audit.do")
    public String audit(Integer[] ids, HttpServletRequest request,
                        RedirectAttributes ra) {
        Site site = Context.getCurrentSite();
        validateIds(ids, site.getId());
        Comment[] beans = service.audit(ids);
        for (Comment bean : beans) {
            logService.operation("opr.comment.audit",
                    StringUtils.substring(bean.getText(), 0, 150), null,
                    bean.getId(), request);
            logger.info("audit Comment, id={}.", bean.getId());
        }
        String infoid = request.getParameter("infoid");
        String ftype = request.getParameter("ftype");
        ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
        ra.addAttribute("infoid", infoid);
        ra.addAttribute("ftype", ftype);
        return "redirect:list.do";
    }

    /**
     * 撤销审核
     * @param ids 评论id
     * @param request
     * @param ra
     * @return
     */
    @RequiresPermissions("core:comment:anti_audit")
    @RequestMapping("anti_audit.do")
    public String antiAudit(Integer[] ids, HttpServletRequest request,
                            RedirectAttributes ra) {
        Site site = Context.getCurrentSite();
        validateIds(ids, site.getId());
        Comment[] beans = service.unaudit(ids);
        for (Comment bean : beans) {
            logService.operation("opr.comment.antiAudit",
                    StringUtils.substring(bean.getText(), 0, 150), null,
                    bean.getId(), request);
            logger.info("unaudit Comment, id={}.", bean.getId());
        }
        String infoid = request.getParameter("infoid");
        String ftype = request.getParameter("ftype");
        ra.addAttribute("infoid", infoid);
        ra.addAttribute("ftype", ftype);
        ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
        return "redirect:list.do";
    }

    // 创建回复
    @RequiresPermissions("core:comment:reply")
    @RequestMapping("replycreate.do")
    public String replycreate(Integer id, org.springframework.ui.Model modelMap, HttpServletRequest request) {

        String infoid = request.getParameter("infoid");
        String ftype = request.getParameter("ftype");
        String fid=request.getParameter("fid");
        modelMap.addAttribute(OPRT, CREATE);
        modelMap.addAttribute("infoid", infoid);
        modelMap.addAttribute("commentId", id);
        modelMap.addAttribute("ftype", ftype);
        modelMap.addAttribute("fid", fid);
        return "core/comment/reply_comment_form";
    }
    
    // 保存回复
    @RequiresPermissions("core:comment:reply")
    @RequestMapping("replysave.do")
    public String replysave(String text,Integer infoid, Integer parentId, String redirect,
                       HttpServletRequest request, RedirectAttributes ra) {
        Integer siteId = Context.getCurrentSiteId();
        Integer userId = Context.getCurrentUserId();
        String ip = Servlets.getRemoteAddr(request);
        String fid=request.getParameter("fid");
        Comment parent=service.get(parentId);
        Info info=infoQueryService.get(Integer.parseInt(fid));
        if(info!=null && parent!=null && parent.getParent()==null && parent.getStatus().intValue()==Comment.AUDITED && "Info".equals(parent.getFtype())){
            InfoComment bean=new InfoComment();
            bean.setStatus(Comment.AUDITED);
            bean.setIp(ip);
            bean.setInfo(info);
            bean.setFtype("Info");
            bean.setText(text);
            bean.setFid(Integer.parseInt(fid));
            service.save(bean, userId, siteId, parentId);
            logService.operation("opr.comment.replysave",
                    StringUtils.substring(bean.getText(), 0, 150), null,
                    bean.getId(), request);
            logger.info("replysave Comment, id={}.", bean.getId());
            ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        }else{
            ra.addFlashAttribute(MESSAGE,OPERATION_FAILURE);
        }
        ra.addAttribute("infoid",infoid);
        return "redirect:list.do";
    }
    
    // 创建全部回复
    @RequiresPermissions("core:comment:reply")
    @RequestMapping("replyAllCreate.do")
    public String replyAllCreate(Integer[] ids, org.springframework.ui.Model modelMap, HttpServletRequest request) {
        modelMap.addAttribute(OPRT, CREATE);
        modelMap.addAttribute("ids", ids);
        return "core/comment/replyall_comment_form";
    }
    
	// 新增需求
    // 保存全部回复
    @RequiresPermissions("core:comment:reply")
    @RequestMapping("replyAllSave.do")
    public String replyAllSave(String text,String idList, String redirect,
                       HttpServletRequest request, RedirectAttributes ra) {
        Integer siteId = Context.getCurrentSiteId();
        Integer userId = Context.getCurrentUserId();
        String ip = Servlets.getRemoteAddr(request);
        Site site = Context.getCurrentSite();
        
        int successCount = 0;
        String[] idListSplit = idList.split(",");

        ArrayList<Integer> ids = new ArrayList<Integer>();
        for(String s : idListSplit) {
        	if(s != null && !s.equals(""))
        		ids.add(Integer.parseInt(s));
        }

        for(Integer id : ids) {
        	Comment parent=service.get(id);
        	if(parent != null) {
        		int fid = parent.getFid();
        		int parentId = parent.getId();
        		Info info=infoQueryService.get(fid);
        		if(info!=null && parent.getParent()==null && parent.getStatus().intValue()==Comment.AUDITED
        				&& "Info".equals(parent.getFtype())){
        			InfoComment bean=new InfoComment();
                    bean.setStatus(Comment.AUDITED);
                    bean.setIp(ip);
                    bean.setInfo(info);
                    bean.setFtype("Info");
                    bean.setText(text);
                    bean.setFid(fid);
                    service.save(bean, userId, siteId, parentId);
                    logService.operation("opr.comment.replysave",
                            StringUtils.substring(bean.getText(), 0, 150), null,
                            bean.getId(), request);
                    logger.info("replysave Comment, id={}.", bean.getId());
                    successCount++;
        		}
        	}	
        }
        if(successCount > 0) {
        	ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        } else {
        	ra.addFlashAttribute(MESSAGE,OPERATION_FAILURE);
        }

        String infoid = request.getParameter("infoid");
        ra.addAttribute("infoid",infoid);
        return "redirect:list.do";
    }

    /**
     * 获取MultipartFile
     * @param request
     * @return
     */
    protected MultipartFile getMultipartFileInfo(HttpServletRequest request){
        return getMultipartFile(request);
    }

    private MultipartFile getMultipartFile(HttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        if (CollectionUtils.isEmpty(fileMap)) {
            throw new IllegalStateException("No upload file found!");
        }
        return fileMap.entrySet().iterator().next().getValue();
    }

    @RequiresPermissions("core:comment:upload")
    @RequestMapping("upload.do")
    public String upload(Integer position, HttpServletRequest request, org.springframework.ui.Model modelMap) {
        return "core/comment/comment_upload";

    }

    /**
     * 上传水军评论
     * @param request
     * @param response
     * @throws Exception
     */
    @RequiresPermissions("core:comment:upload")
    @RequestMapping(value = "uploadComment.do", method = RequestMethod.POST)
    public void uploadComment(HttpServletRequest request,HttpServletResponse response) throws Exception {
        MultipartFile multipartFile = getMultipartFileInfo(request);
        //验证
        ExcelUtil.checkFile(multipartFile);
        Site site = Context.getCurrentSite();
        User user=Context.getCurrentUser(); //当前操作用户
        String ip = Servlets.getRemoteAddr(request);
        UploadResult result = new UploadResult();
        Locale locale = RequestContextUtils.getLocale(request);
        result.setMessageSource(messageSource, locale);
//        uploadHandler.upload(multipartFile, Uploader.FILE, site, user.getId(), ip, result, null, null, null, null, null,null, null, null);
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        logService.operation("core:comment:upload",multipartFile.getName(), null,null, ip, user.getId(), site.getId());
        //获取上传的excel文件
        int count=0;
        Map<Integer,List<JSONObject>> pushMap=new HashMap<>();
        try {
            List<WaterComment> list = ExcelImportUtil.importExcel(multipartFile.getInputStream(), WaterComment.class,params);
            if(list!=null && list.size()>0){
                Random random = new Random(); //随机数
                PageRequest pageable=new PageRequest(0,list.size(),new Sort(Direction.DESC,"id"));
                Map<String,String[]> paramMap=new HashMap<String,String[]>();
                paramMap.put("STARTWITH_username",new String[]{"9"});
                Page<User> pagedList = userService.findPage(0, null, null, paramMap, pageable);
                List<User> userList=pagedList.getContent();
                for(WaterComment com:list){
                    if(com!=null && StringUtils.isNotBlank(com.getId()) && StringUtils.isNotBlank(com.getText()) && StringUtils.isNotBlank(com.getType())){

                        if(userList==null || userList.size()==0 ||count>=1000){
                            break;
                        }

                        int ran = random.nextInt(userList.size());//随机数

                        Integer commentUserId=userList.get(ran).getId(); //获取用户名9开头的随机用户

                        Integer id=Integer.parseInt(com.getId());

                        //类型(0新闻1直播)
                        if("0".equals(com.getType())){
                            Info info=infoQueryService.get(id);
                            if(info!=null){
                                InfoComment bean=new InfoComment();
                                bean.setStatus(Comment.AUDITED);
                                bean.setIp(ip);
                                bean.setFtype("Info");
                                bean.setText(com.getText());
                                bean.setFid(id);

                                //设置审核人，审核时间
                                bean.setAuditor(user);
                                bean.setAuditDate(new Date());
                                //设置创建时间,当前时间减去随机0-120秒
                                int seconds=random.nextInt(120)*1000;
                                bean.setCreationDate(new Timestamp(System.currentTimeMillis()-seconds));
                                service.save(bean, commentUserId, site.getId(), null);
                                //记录操作日志
                                logService.operation("core:comment:upload",
                                        StringUtils.substring(bean.getText(), 0, 150), null,
                                        bean.getId(), request);
                                logger.info("core:comment:upload, infoid={}.", bean.getId());
                            }
                        }
                        if("1".equals(com.getType())){
                            LiveBroadcast live=liveBroadcastService.get(id);
                            if(live!=null){
                                LiveComment bean=new LiveComment();
                                bean.setStatus(Comment.AUDITED);
                                bean.setIp(ip);
                                bean.setFtype("Live");
                                bean.setText(com.getText());
                                bean.setFid(id);

                                //设置审核人，审核时间
                                bean.setAuditor(user);
                                bean.setAuditDate(new Date());
                                //设置创建时间,当前时间减去随机0-120秒
                                int seconds=random.nextInt(120)*1000;
                                bean.setCreationDate(new Timestamp(System.currentTimeMillis()-seconds));

                                Comment liveComemt=service.save(bean, commentUserId, site.getId(), null);

                                //组装推送数据
                                List<JSONObject> liveComentJsons =pushMap.get(id);
                                if(liveComentJsons==null){
                                    liveComentJsons=new ArrayList<>();
                                }
                                JSONObject commentjson = new JSONObject();
                                User user1 = liveComemt.getCreator();
                                if (user1 != null) {
                                    Integer userId = user1.getId();
                                    String nickName = user1.getNickname();
                                    String iph =user1.getUsername();
                                    String avatar = user1.getAvatarSmall();
                                    commentjson.put("userId", id == null ? "" : id);
                                    commentjson.put("avatar", avatar == null ? "" : avatar);
                                    commentjson.put("nickName", nickName == null ? iph==null?"匿名":((iph.length() > 10) ? iph.substring(0,4)+"*******":iph) : nickName);
                                }
                                commentjson.put("commentId",liveComemt.getId());
                                commentjson.put("comment", liveComemt.getText());//bean.getTime() == null ? "" : Dates.formatDate(bean.getTime(), "yyyy-MM-dd HH:mm:ss")
                                commentjson.put("pubTime", liveComemt.getCreationDate() == null ? "" : Dates.formatDate(liveComemt.getCreationDate(), "yyyy-MM-dd HH:mm:ss"));
                                commentjson.put("liveId",liveComemt.getFid());
                                liveComentJsons.add(commentjson);
                                pushMap.put(id,liveComentJsons);

                                //记录操作日志
                                logService.operation("core:comment:upload",
                                        StringUtils.substring(bean.getText(), 0, 150), null,
                                        bean.getId(), request);
                                logger.info("core:comment:upload, liveid={}.", bean.getId());
                            }
                        }
                        count++;
                    }
                }
                result.setMessage("上传成功!");
            }

            //推送
            for(Integer id:pushMap.keySet()){
                List<JSONObject> jsonJushs=pushMap.get(id);
                List<JSONObject> fives=new ArrayList<>(); //每次推送五条聊天室数据
                for(int i=0;i<jsonJushs.size();i++){
                    JSONObject jsonObject=jsonJushs.get(i);
                    fives.add(jsonObject);
                    boolean flag=false;
                    if(fives.size()==5){
                        flag=true;
                    }
                    if(i==jsonJushs.size()-1){
                        flag=true;
                    }
                    if(flag){
                        JSONObject push = new JSONObject();
                        JSONObject extr = new JSONObject();
                        extr.put("pushType", 2);//0正常、1推送直播间动态、2聊天室
                        extr.put("data", fives);

                        push.put("title", "");//通知内容标题
                        push.put("msgTile", "");//消息内容标题
                        push.put("content", "直播聊天室");//消息内容
                        push.put("isOpen", true);//是否静默
                        push.put("groupTag", id.toString());//分组信息
                        push.put("extrasparam", extr);//扩展字段
                        try {
                            jpushService.JpushIosOrAndroid(site, user, push);
                        } catch (Exception e) {
                        }
                        fives=new ArrayList<JSONObject>();
                    }
                }
            }
        } catch (Exception e) {
            result.setMessage("上传失败，请检查表格，重试!");
            result.setError(e.getMessage());
            e.printStackTrace();
            logger.error("upload comment fail");
        }

        Servlets.writeHtml(response, JSONObject.toJSONString(result));
    }

    @ModelAttribute("bean")
    public Comment preloadBean(@RequestParam(required = false) Integer oid) {
        return oid != null ? service.get(oid) : null;
    }

    private void validateIds(Integer[] ids, Integer siteId) {
        for (Integer id : ids) {
            Backends.validateDataInSite(service.get(id), siteId);
        }
    }

    @Autowired
    private OperationLogService logService;
    @Autowired
    private CommentService service;
    @Autowired
    private InfoQueryService infoQueryService;
    @Autowired
    protected MessageSource messageSource;
    @Autowired
    private UserService userService;
    @Autowired
    private LiveBroadcastService liveBroadcastService;
    @Autowired
    private JpushService jpushService;
}
